package com.antler.smt.admin.service.impl;

import com.antler.smt.admin.mapper.RoleEntityMapper;
import com.antler.smt.admin.mapper.UserEntityMapper;
import com.antler.smt.admin.mapper.UserInfoMapper;
import com.antler.smt.admin.mapper.UserRoleInfoMapper;
import com.antler.smt.admin.utils.ShiroUtils;
import com.antler.smt.constant.DateTimeConstant;
import com.antler.smt.constant.PermissionConstant;
import com.antler.smt.entity.RoleEntity;
import com.antler.smt.entity.UserEntity;
import com.antler.smt.entity.UserRoleEntity;
import com.antler.smt.enums.ResultCodeEnum;
import com.antler.smt.exception.TransactionException;
import com.antler.smt.request.admin.AddUserReq;
import com.antler.smt.request.admin.GetUserListReq;
import com.antler.smt.request.admin.UpdatePwdReq;
import com.antler.smt.request.admin.UpdateUserReq;
import com.antler.smt.response.admin.GetUserListResp;
import com.antler.smt.response.base.Result;
import com.antler.smt.service.admin.UserService;
import com.antler.smt.utils.LogUtil;
import com.antler.smt.utils.StringUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 用户接口实现
 *
 * @author vic
 * @date 2018-03-19 19:53
 */
@Service
public class UserServiceImpl implements UserService {
    /**
     * 日志
     */
    private static Logger log = LogUtil.get();

    /**
     * 用户Mapper
     */
    @Autowired
    private UserInfoMapper userInfoMapper;

    /**
     * 用户角色Mapper
     */
    @Autowired
    private UserRoleInfoMapper userRoleInfoMapper;

    /**
     * 角色实体Mapper
     */
    @Autowired
    private RoleEntityMapper roleEntityMapper;

    /**
     * 用户实体Mapper
     */
    @Autowired
    private UserEntityMapper userEntityMapper;

    /**
     * 获取用户列表信息
     *
     * @param request 请求实体
     * @return 用户列表实体
     */
    @Override
    public Result<PageInfo<GetUserListResp>> listUserInfo(GetUserListReq request) {
        Result result;
        PageHelper.startPage(request.getPageCurrent(), request.getPageSize());
        Page<GetUserListResp> listUserInfo = userInfoMapper.listUserInfo(request);
        if (listUserInfo != null) {
            PageInfo<GetUserListResp> userListPageInfo = new PageInfo(listUserInfo);
            result = new Result(userListPageInfo);
        } else {
            result = new Result(ResultCodeEnum.QUERY_DATA_ERROR, "查询数据为空！");
        }
        return result;
    }

    /**
     * 根据用户id获取用户
     *
     * @param userId 用户id
     * @return 用户实体
     */
    @Override
    public Result<GetUserListResp> getUserByUserId(Long userId) {
        Result result;
        GetUserListResp userInfo = userInfoMapper.getUserByUserId(userId);
        if (userInfo != null) {
            result = new Result(userInfo);
        } else {
            result = new Result(ResultCodeEnum.QUERY_DATA_ERROR, "查询数据为空！");
        }
        return result;
    }

    /**
     * 新增用户
     *
     * @param addUserReq 请求实体
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result addUser(AddUserReq addUserReq) {
        Result result;
        //用户工号
        String jobNum = addUserReq.getJobNum();
        UserEntity userEntity = userInfoMapper.queryByJobNum(jobNum);
        if (userEntity != null) {
            return new Result(ResultCodeEnum.APPEND_DATA_ERROR, "当前用户已经存在!");
        }
        //region 新增用户
        //原密码
        String pwd = addUserReq.getPassword();
        //加密后密码
        String encryptPwd;
        if (StringUtil.isEmpty(pwd)) {
            //设置默认密码123456
            encryptPwd = ShiroUtils.sha256(PermissionConstant.ORIGINAL_PASSWORD);
        } else {
            encryptPwd = ShiroUtils.sha256(pwd);
        }
        addUserReq.setPassword(encryptPwd);
        UserEntity addUserEntity = new UserEntity();
        addUserEntity.setJobNum(addUserReq.getJobNum());
        addUserEntity.setPassword(addUserReq.getPassword());
        addUserEntity.setEmail(addUserReq.getEmail());
        addUserEntity.setMobile(addUserReq.getMobile());
        addUserEntity.setRealName(addUserReq.getRealName());
        Integer addUser = userInfoMapper.addUser(addUserEntity);
        if (addUser <= 0) {
            throw new TransactionException(ResultCodeEnum.APPEND_DATA_ERROR, "新增用户表失败！");
        }
        //endregion
        //region 新增用户角色
        if (addUserReq.getRoleId() <= 0) {
            throw new TransactionException(ResultCodeEnum.APPEND_DATA_ERROR, "角色id不合法！");
        }
        UserRoleEntity userRoleEntity = new UserRoleEntity();
        //新增返回的主键id
        userRoleEntity.setUserId(addUserEntity.getId());
        userRoleEntity.setRoleId(addUserReq.getRoleId());
        Integer addUserRole = userRoleInfoMapper.addUserRole(userRoleEntity);
        if (addUserRole <= 0) {
            throw new TransactionException(ResultCodeEnum.APPEND_DATA_ERROR, "新增用户角色表失败！");
        }
        //endregion
        result = new Result();
        return result;
    }

    /**
     * 更新用户
     *
     * @param req 请求实体
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result updateUser(UpdateUserReq req) {
        Result result;
        //判断用户是否存在
        GetUserListResp userInfo = userInfoMapper.getUserByUserId(req.getUserId());
        if (userInfo == null) {
            return new Result(ResultCodeEnum.QUERY_DATA_ERROR, "需要更新的用户不存在!");
        }
        //region 更新用户
        Integer updateUser = userInfoMapper.updateUser(req);
        if (updateUser <= 0) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "更新用户表失败！");
        }
        //endregion
        //region 更新用户角色表
        //检查用户是否被赋予角色
        if (userRoleInfoMapper.checkUserHasRole(req.getUserId()) > 0) {
            Integer delete = userRoleInfoMapper.deleteUserRole(req.getUserId());
            if (delete <= 0) {
                throw new TransactionException(ResultCodeEnum.DELETE_DATA_ERROR, "删除用户角色表失败！");
            }
        }
        //定义用户角色实体
        if (req.getRoleId() <= 0) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "角色id不合法！");
        }
        RoleEntity roleEntity = roleEntityMapper.selectByPrimaryKey(req.getRoleId());
        if (roleEntity == null) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "当前角色id对应的角色不存在！");
        }
        UserRoleEntity userRoleEntity = new UserRoleEntity();
        userRoleEntity.setUserId(req.getUserId());
        userRoleEntity.setRoleId(req.getRoleId());
        Integer addUserRole = userRoleInfoMapper.addUserRole(userRoleEntity);
        if (addUserRole <= 0) {
            throw new TransactionException(ResultCodeEnum.APPEND_DATA_ERROR, "新增用户角色表失败！");
        }
        //endregion
        result = new Result();
        return result;
    }

    /**
     * 删除用户
     *
     * @param userId 用户id
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result deleteUser(Long userId) {
        Result result = new Result();
        //判断用户是否存在
        GetUserListResp userInfo = userInfoMapper.getUserByUserId(userId);
        if (userInfo == null) {
            return new Result(ResultCodeEnum.QUERY_DATA_ERROR, "需要删除的用户不存在!");
        }
        //region 删除用户表
        Integer deleteUser = userInfoMapper.deleteUser(userId);
        if (deleteUser <= 0) {
            throw new TransactionException(ResultCodeEnum.DELETE_DATA_ERROR, "删除用户表失败！");
        }
        //endregion
        //region 删除用户角色表
        //检查用户是否被赋予角色
        if (userRoleInfoMapper.checkUserHasRole(userId) > 0) {
            Integer deleteUserRole = userRoleInfoMapper.deleteUserRole(userId);
            if (deleteUserRole <= 0) {
                throw new TransactionException(ResultCodeEnum.DELETE_DATA_ERROR, "删除用户角色表失败！");
            }
        }
        //endregion
        return result;
    }

    /**
     * 批量删除用户
     *
     * @param userIds 用户id列表
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result batchDeleteUser(List<Long> userIds) {
        Result result = new Result();
        //region 批量删除用户表
        Integer deleteUser = userInfoMapper.batchDeleteUser(userIds);
        if (deleteUser <= 0) {
            throw new TransactionException(ResultCodeEnum.DELETE_DATA_ERROR, "批量删除用户表失败！");
        }
        //endregion
        //region 批量删除用户角色表
        Integer deleteUserRole = userRoleInfoMapper.batchDeleteUserRole(userIds);
        if (deleteUserRole <= 0) {
            throw new TransactionException(ResultCodeEnum.DELETE_DATA_ERROR, "批量删除用户角色表失败！");
        }
        //endregion
        return result;
    }

    /**
     * 修改密码
     *
     * @param updatePwdReq 请求实体
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result updatePassword(UpdatePwdReq updatePwdReq) {
        Result result = new Result();
        //sha256加密
        updatePwdReq.setOldPassword(ShiroUtils.sha256(updatePwdReq.getOldPassword()));
        updatePwdReq.setNewPassword(ShiroUtils.sha256(updatePwdReq.getNewPassword()));
        Integer updatePassword = userInfoMapper.updatePassword(updatePwdReq);
        if (updatePassword == 0) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "原密码不正确！");
        } else if (updatePassword != 1) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "修改密码失败！");
        }
        return result;
    }

    /**
     * 初始化密码
     *
     * @param userId 用户id
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result initPassword(Long userId) {
        Result result = new Result();
        //sha256加密
        UserEntity userEntity = new UserEntity();
        userEntity.setPassword(ShiroUtils.sha256(PermissionConstant.ORIGINAL_PASSWORD));
        userEntity.setId(userId);
        Integer initPassword = userInfoMapper.initPassword(userEntity);
        if (initPassword <= 0) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "初始化密码失败！");
        }
        return result;
    }

    /**
     * 批量初始化密码
     *
     * @param userIds 用户id列表
     * @return Result实体
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = DateTimeConstant.MINUTE_S, rollbackFor = Exception.class)
    public Result batchInitPassword(List<Long> userIds) {
        Result result = new Result();
        int size = userIds.size();
        int successCount = 0;
        for (long userId : userIds) {
            //sha256加密
            UserEntity userEntity = new UserEntity();
            userEntity.setPassword(ShiroUtils.sha256(PermissionConstant.ORIGINAL_PASSWORD));
            userEntity.setId(userId);
            Integer initPassword = userInfoMapper.initPassword(userEntity);
            if (initPassword == 1) {
                successCount++;
            }
        }
        if (size != successCount) {
            throw new TransactionException(ResultCodeEnum.MODIFY_DATA_ERROR, "批量初始化密码失败！");
        }
        return result;
    }

    /**
     * 更新最后登录时间
     *
     * @param userId 用户id
     * @return 影响行数
     */
    @Override
    public Integer updateLastLoginTime(Long userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(userId);
        userEntity.setLastLoginTime(new Date());
        return userEntityMapper.updateByPrimaryKeySelective(userEntity);
    }

    /**
     * 根据用户获取所有的权限标识
     *
     * @param userId 用户id
     * @return 权限标识列表
     */
    @Override
    public List<String> queryAllPerms(Long userId) {
        return userInfoMapper.queryAllPerms(userId);
    }

    /**
     * 通过工号获取用户信息
     *
     * @param jobNum 工号
     * @return 用户信息
     */
    @Override
    public UserEntity queryByJobNum(String jobNum) {
        return userInfoMapper.queryByJobNum(jobNum);
    }

    /**
     * 根据用户获取所有的权限Id
     *
     * @param userId 用户id
     * @return 权限id列表
     */
    @Override
    public List<Long> queryAllPermissionId(Long userId) {
        return userInfoMapper.queryAllPermissionId(userId);
    }
}
